package com.meida.module.product.provider.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.meida.common.constants.CommonConstants;
import com.meida.common.enums.StateEnum;
import com.meida.common.enums.VisiableEnum;
import com.meida.common.mybatis.base.service.impl.BaseServiceImpl;
import com.meida.common.mybatis.entity.EntityMap;
import com.meida.common.mybatis.model.PageModel;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.mybatis.model.SaveModel;
import com.meida.common.mybatis.query.CriteriaDelete;
import com.meida.common.mybatis.query.CriteriaQuery;
import com.meida.common.mybatis.query.CriteriaSave;
import com.meida.common.security.OpenHelper;
import com.meida.common.utils.FlymeUtils;
import com.meida.module.product.client.entity.ProdGroup;
import com.meida.module.product.provider.mapper.ProdGroupMapper;
import com.meida.module.product.provider.service.ProdGroupProductService;
import com.meida.module.product.provider.service.ProdGroupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 店铺产品分类 实现类
 *
 * @author flyme
 * @date 2019-07-02
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ProdGroupServiceImpl extends BaseServiceImpl<ProdGroupMapper, ProdGroup> implements ProdGroupService {

    @Autowired
    private ProdGroupProductService prodGroupProductService;

    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public ResultBody selectProductGroup(Long companyId) {
        CriteriaQuery cq = new CriteriaQuery(ProdGroup.class);
        cq.select(ProdGroup.class, "groupId", "groupName", "parentId", "groupLevel");
        cq.eq(true, "companyId", companyId);
        cq.orderByAsc("sortOrder");
        List<EntityMap> allList = selectEntityMap(cq);
        List<EntityMap> result = buildTree(allList, 0L);
        return ResultBody.ok(result);
    }


    /**
     * 递归构建
     *
     * @param list
     * @param parentId
     * @return
     */
    private static List<EntityMap> buildTree(List<EntityMap> list, Long parentId) {
        List<EntityMap> result = new ArrayList();
        list.forEach(category -> {
            Long groupId = category.getLong("groupId");
            Long pid = category.getLong("parentId");
            Integer groupLevel = category.get("groupLevel");
            if (parentId.equals(pid)) {
                List child = buildTree(list, groupId);
                if (groupLevel.equals(1)) {
                    category.put("child", child);
                }
                result.add(category);
            }
        });
        return result;
    }


    @Override
    public ResultBody beforeListEntityMap(CriteriaQuery<ProdGroup> cq, ProdGroup prodGroup, EntityMap requestMap) {
        Long companyId = OpenHelper.getCompanyId();
        cq.eq(ProdGroup.class, "companyId", companyId);
        cq.eq(ProdGroup.class, "groupLevel");
        cq.likeByField(ProdGroup.class, "groupName");
        cq.select(ProdGroup.class, "groupId", "groupName", "parentId", "sortOrder", "groupState");
        cq.orderByAsc("sortOrder");
        cq.orderByAsc("sortOrder");
        return ResultBody.ok();
    }

    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public ResultBody pageList(PageModel model) {
        CriteriaQuery cq = new CriteriaQuery(model, ProdGroup.class);
        Long companyId = OpenHelper.getCompanyId();
        cq.select(ProdGroup.class, "groupId", "groupName", "sortOrder", "groupState");
        cq.eq(ProdGroup.class, "groupLevel");
        cq.eq(ProdGroup.class, "groupState", CommonConstants.ENABLED);
        cq.eq(ProdGroup.class, "parentId");
        cq.likeByField(ProdGroup.class, "groupName");
        cq.eq(ProdGroup.class, "companyId", companyId);
        cq.orderByAsc("sortOrder");
        return basePageList(cq);
    }


    @Override
    public ResultBody add(SaveModel model) {
        CriteriaSave cs = new CriteriaSave(model, ProdGroup.class);
        Long companyId = OpenHelper.getCompanyId();
        EntityMap params = cs.getRequestMap();
        Long parentId = params.getLong("parentId");
        Integer groupLevel = 1;
        if (FlymeUtils.isEmpty(parentId) || parentId.equals(0L)) {
            parentId = 0L;
        } else {
            QueryWrapper qw = new QueryWrapper();
            qw.eq("groupId", parentId);
            ProdGroup prodGroup = getOne(qw);
            groupLevel = prodGroup.getGroupLevel() + 1;
        }
        cs.put("parentId", parentId);
        cs.put("groupState", StateEnum.ENABLE.getCode());
        cs.put("companyId", companyId);
        cs.put("groupLevel", groupLevel);
        return baseAdd(cs);
    }

    @Override
    public ResultBody setState(Long groupId) {
        ProdGroup prodGroup = getById(groupId);
        Integer groupState = prodGroup.getGroupState();
        if (groupState.equals(VisiableEnum.SHOW.getCode())) {
            prodGroup.setGroupState(VisiableEnum.HIDE.getCode());

        } else {
            prodGroup.setGroupState(VisiableEnum.SHOW.getCode());
        }
        saveOrUpdate(prodGroup);
        return ResultBody.ok("设置成功", prodGroup.getGroupState());
    }

    @Override
    public List<Long> selectByParenId(Long parentId) {
        CriteriaQuery<ProdGroup> cq = new CriteriaQuery(ProdGroup.class);
        cq.select("groupId");
        cq.eq("parentId",parentId);
        return listObjs(cq, e -> Long.parseLong(e.toString()));
    }

    @Override
    public ResultBody beforeDelete(CriteriaDelete<ProdGroup> cd) {
        Long groupId = cd.getIdValue();
        int n = prodGroupProductService.countByGroupId(groupId);
        if (n > 0) {
            return ResultBody.failed("该分类已使用禁止删除");
        } else {
            return ResultBody.ok();
        }
    }
}
